/**
 * 2021-03-05: 优化state中  columns: [],  posts: [],，  把数组转成对象，参见helper.ts TestProps
*/


import { createStore, Commit } from "vuex";
import axios from "axios";
import { arrToObj, objToArr} from '@/utils/helper'

// ajax返回数据格式
export interface ResponseType<T = {}> {
  code: number
  msg: string
  success?: boolean
  data: T       // 泛型，默认空对象
}

// 用户
export interface UserProps {
  isLogin: boolean;
  nickName?: string;
  _id?: string;
  column?: string;
  email?: string;
}
// 头像
export interface ImageProps {
  _id?: string; 
  url?: string; 
  createdAt?: string;
}

// 专栏
export interface ColumnProps {
  _id: string;
  title: string;
  avatar?: ImageProps;
  description: string;
}

// 专栏文章
export interface PostProps {
  _id: string;
  title: string;
  excerpt?: string;    // 文章摘要
  content?: string;    // 文章内容
  image?: ImageProps | string;
  createdAt: string;
  column: string;      // 专栏id，与ColumnProps中_id对应
  author?: string;
}

// 2021-03-05: 优化state中  columns: [],  posts: [],，  把数组转成对象，参见helper.ts TestProps
// 描述一个对象： key为一个字符串， value是一个T类型的对象
interface ListProps<P> {
  [id: string]: P
}

// 全局数据
export interface GlobalDataProps {
  token: string,
  isLoading: boolean,
  user: UserProps;
  // columns: ColumnProps[];  // Array<ColumnProps>
  // posts: PostProps[];

  columns: ListProps<ColumnProps>;
  posts: ListProps<PostProps>;
  error: GolbalErrorProps;
}

// 全局错误提示
export interface GolbalErrorProps {
  status: boolean;
  message?: string;
}

// get请求
const getAndCommit = async(url: string, mutationName: string, commit: Commit) => {
  const { data } = await axios.get(url);
  commit(mutationName, data)
}

// post请求
const postAndCommit = async(url: string, mutationName: string, commit: Commit, payload: any ) => {
  const { data }  = await axios.get(url, payload);
  commit(mutationName, data);
  return data;
}

export default createStore<GlobalDataProps>({
  state: {
    error: { status: false },
    token: localStorage.getItem("token") || '',
    isLoading: false,
    // 2021-03-05: 优化state中  columns: [],  posts: [],，  把数组转成对象，参见helper.ts TestProps
    columns: {},
    posts: {},
    // columns: [],
    // posts: [],
    user: {
      isLogin: false
    }
  },

  getters: {
    getColumns:(state) => {
      return objToArr( state.columns )
    },

    getColumnById: (state) => (id: string) => {
      // 找一个成员用find， 避免用filter找到多个取下标为0的元素
      // return state.columns.find( c => c._id === id)
      return state.columns[id]
    },

    getPostsByCid: (state) => (cid: string) => {
      // 找多个成员用filter
      // return state.posts.filter( post => post.column === cid)
      return objToArr(state.posts).filter(post => post.column === cid)
    },
   
  },

  mutations: {
     
    createPosts( state, newPost) {
      // state.posts.push( newPost );
      state.posts[newPost._id] = newPost
    },
    
    // 专栏列表
    fetchColumns(state, columns) {
      // state.columns = columns
      state.columns = arrToObj(columns);   // arrToObj(rawData.data.list)
      console.log("state.columns==",state.columns)
    },
    
    // 某个专栏文章信息
    fetchColumn(state, rawData) {
      console.log("rawData==",rawData)
      // state.columns = columns
      state.columns[rawData.data._id] = rawData.data
    },

    // 某个专栏下的文章列表
    fetchPosts(state, posts) {
      state.posts = arrToObj(posts)
    },

    setLoading( state, status ) {
      state.isLoading = status
    },

    login(state, rawData) {
      const token =  rawData.data.token;
      state.token = token;
      localStorage.setItem('token', token)
      axios.defaults.headers.common.Authorization = `Bear ${token}`
    },

    fetchCurrentUser(state, rawData) {
      state.user = { isLogin: true, ...rawData.data}
    },

    setError(state, e: GolbalErrorProps) {
      state.error = e;
    },

    logout(state) {
      localStorage.clear();
      state.token = '';
      delete axios.defaults.headers.common.Authorization;
    }
   
  },

  actions: {
    fetchColumns({commit}) {
     return getAndCommit(`/json/column.json`, 'fetchColumns', commit)
    },

    fetchColumn({commit}){
      return getAndCommit(`/json/myColumnInfo.json`, 'fetchColumn', commit)
    },
   
    fetchPosts({commit}){
      return getAndCommit(`/json/post.json`, 'fetchPosts', commit)
    },
    

    // 获取专栏下的文章内容
    async fetchPostDetail({commit}, id){
        let detailData = await axios.get(`/json/postDetail.json`)
        return detailData;
    },

    async login({commit}, payload) {
      commit('setError', {status: false, message: ''})
      console.log("login==");
      const { email, password } = payload;
      // 模拟登录出错
      if(email !='maping6462@163.com' || password != '123456') {
        const errorData = {
          status: 404,
          statusText: 'Not Found',
          data: {
            code: 404,
            message: '该用户不存在或者密码不正确'
          }
        }
        commit("setLoading", false)
        commit('setError', {status: true, message: errorData.data.message})
        return Promise.reject(errorData);
      }

      return postAndCommit(`/json/login.json`, 'login', commit, payload)
    },

    fetchCurrentUser({commit}) {
      return getAndCommit(`/json/currentUser.json`, 'fetchCurrentUser', commit)
    },
    
    // 触发login 然后再触发fetchCurrentUser
    // 登录成功后获取token， 然后再获取用户信息
    loginAndFetch({ dispatch }, loginData) {
      return dispatch('login', loginData).then(() => {
        return dispatch('fetchCurrentUser')
      })
    },

    createPosts({commit}, payload) {
      return postAndCommit(`/json/createPost.json`, 'createPosts', commit, payload)
    }

  },

  modules: {
  }
})
